package yhao.demo.autocode.core.method;

import org.apache.commons.lang3.StringUtils;
import yhao.demo.autocode.core.AutoCodeUtils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class NewMethodHelper {
    /**
     * @param methodName 方法名
     * @param httpMethod http请求
     * @param apiUrlPath 请求路径前缀
     * @param beanPrefix 通用对象前缀，用于通名bean
     * @param formInfo 传参form
     * @param returnObjectType 返回值类型枚举
     * @param apiDesc api描述
     * @param apiReturnDesc api返回值描述
     */
    public NewMethodHelper(String methodName,HttpMethodEnum httpMethod,
                           String apiUrlPath,
                           String beanPrefix,FormInfo formInfo,
                           ReturnTypeEnum returnObjectType,
                           String apiDesc,String apiReturnDesc) {
        this.methodName = methodName;
        this.httpMethod = httpMethod;
        this.apiUrlPath = apiUrlPath;
        this.beanPrefix = beanPrefix;
        this.formInfo = formInfo;
        this.returnObject = formInfo.getFormName();
        this.returnObjectType = returnObjectType;
        this.apiDesc = apiDesc;
        this.apiReturnDesc = apiReturnDesc;
        if(StringUtils.isEmpty(methodName)){
            throw new RuntimeException("methodName不得为空");
        }
    }

    //方法名
    private String methodName;

    //方法类型
    private HttpMethodEnum httpMethod;

    //请求路径前缀
    private String apiUrlPath;

    //api描述
    private String apiDesc;

    //api返回值描述
    private String apiReturnDesc;

    //api返回值对象类型
    private String returnObject;

    //返回值类型枚举
    private ReturnTypeEnum returnObjectType;

    //通用对象前缀，用于通名bean
    private String beanPrefix;
    //传参form
    private FormInfo formInfo;

    private String remoteName;
    private String feignName;
    private String serviceName;
    private String daoName;

    private String rootDir;

    public enum HttpMethodEnum{
        GET("GetMapping"),
        POST("PostMapping"),
        ;

        private String desc;

        HttpMethodEnum(String desc) {
            this.desc = desc;
        }
    }

    public enum ReturnTypeEnum{
        ALONE("单独对象"),
        LIST("List对象"),
        PAGINATION("分页对象"),
        ;

        private String desc;

        ReturnTypeEnum(String desc) {
            this.desc = desc;
        }
    }

    public final static String CONF_DIR_PATH =
            System.getProperty("user.home") + File.separator + "yhao.newmethod";

    public void doNew() throws IOException {
        System.out.println(toString());
        System.out.println("开始生成项目文件...");

        System.out.println("开始生成根目录...");
        makeRoot();
        System.out.println("开始生成根目录...DONE");

        System.out.println("开始生成代码文件...");
        makeMethod();
        if(formInfo.isCustom()){
            System.out.println("开始生成Form文件...");
            makeForm();
            System.out.println("开始生成Form文件...DONE");
        }
        System.out.println("开始生成代码文件...DONE");

        System.out.println("生成项目文件...DONE");
        System.out.println("完成操作...");
        System.out.println("请到以下地址复制文件..." + CONF_DIR_PATH);
    }

    private void makeForm() throws IOException {
        StringBuffer formAll = new StringBuffer();
        formAll.append(String.format("package form;\n\n"));
        formAll.append("@ApiModel\n");
        formAll.append(String.format("public class %s %s {\n",formInfo.getFormName(),
                StringUtils.isNotEmpty(formInfo.getExtendsForm())?
                        "extends "+formInfo.getExtendsForm():"implements ValidationForm"));

        StringBuffer formFieldSb = new StringBuffer();
        StringBuffer getSetSb = new StringBuffer();
        for (FormFieldInfo fieldInfo:formInfo.getFieldList()) {
            String objectField = fieldInfo.getFieldName();
            String fieldType = fieldInfo.getFieldType();
            //field
            formFieldSb.append(String.format("\t@ApiModelProperty(value = \"%s\"%s)\n",
                    fieldInfo.getDesc(),fieldInfo.isCanNull()?"":",required = true"));
            if(!fieldInfo.isCanNull()){
                formFieldSb.append(String.format("\t%s(message = \"请输入%s\")\n",
                        fieldType.equals("String")?"@NotBlank":"@NotNull",fieldInfo.getDesc()));
            }
            formFieldSb.append(String.format("\tprivate %s %s;\n\n", fieldType, objectField));

            //getSet方法
            String _objectField = (objectField.charAt(0) + "").toUpperCase() + objectField.substring(1);

            getSetSb.append(String.format("\tpublic void set%s(%s %s){\n", _objectField, fieldType, objectField));
            getSetSb.append(String.format("\t\tthis.%s = %s;\n\t}\n\n", objectField, objectField));
            getSetSb.append(String.format("\tpublic %s get%s(){\n", fieldType, _objectField));
            getSetSb.append(String.format("\t\treturn %s;\n\t}\n\n", objectField));
        }
        formAll.append(formFieldSb).append("\n");
        formAll.append(getSetSb);
        formAll.append("}\n");
        AutoCodeUtils.makeFile(rootDir,formInfo.getFormName()+".java",formAll.toString());
    }

    private void makeMethod() throws IOException {
        String content = AutoCodeUtils.readResource("newMethod/method.new");
        String returnObjectWithType = returnObject;
        String authAnnotation = "//TODO 权限注解 @AuthorityAnnotation(AuthorityAnnotationEnums.)";
        if(returnObjectType.equals(ReturnTypeEnum.ALONE)){
            returnObjectWithType = returnObject;
        }else if(returnObjectType.equals(ReturnTypeEnum.LIST)){
            returnObjectWithType = "List<"+returnObject+">";
        }else if(returnObjectType.equals(ReturnTypeEnum.PAGINATION)){
            returnObjectWithType = "Pagination<"+returnObject+">";
        }

        Map<String,String> param = new HashMap<>();
        param.put("methodName",methodName);
        param.put("httpMethod",httpMethod.desc);
        param.put("apiUrlPath",apiUrlPath);
        param.put("authAnnotation",authAnnotation);
        param.put("apiDesc",apiDesc);
        param.put("apiReturnDesc",apiReturnDesc);
        param.put("returnObject",returnObject);
        param.put("formName",formInfo.getFormName());
        param.put("returnObjectWithType",returnObjectWithType);
        param.put("remoteName",StringUtils.isBlank(remoteName)?beanPrefix+"Remote":remoteName);
        param.put("feignName",StringUtils.isBlank(feignName)?beanPrefix+"Feign":feignName);
        param.put("serviceName",StringUtils.isBlank(serviceName)?beanPrefix+"Service":serviceName);
        param.put("daoName",StringUtils.isBlank(daoName)?beanPrefix+"Dao":daoName);
        param.put("requestBody",httpMethod.equals(HttpMethodEnum.GET)?"":"@RequestBody ");
        AutoCodeUtils.deleteFile(rootDir,"method.txt");

        content = AutoCodeUtils.replacePlaceHolder(content,param);
        AutoCodeUtils.makeFile(rootDir,"method.txt",content);
    }

    private void makeRoot() {
        File root = new File(CONF_DIR_PATH);
        String fileDirPath = CONF_DIR_PATH + File.separator + methodName;
        if (!root.exists()) {
            root.mkdir();
        }
        File fileDir = new File(fileDirPath);
        if (!fileDir.exists()) {
            fileDir.mkdir();
        }
        rootDir = fileDirPath;
    }

    public void setRemoteName(String remoteName) {
        this.remoteName = remoteName;
    }

    public void setFeignName(String feignName) {
        this.feignName = feignName;
    }

    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }

    public void setDaoName(String daoName) {
        this.daoName = daoName;
    }
}
